package cntv.player.core.util;

import android.view.View;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.view.animation.Animation.AnimationListener;
import android.view.animation.AnimationSet;
import android.view.animation.AnticipateInterpolator;
import android.view.animation.AnticipateOvershootInterpolator;
import android.view.animation.BounceInterpolator;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.LinearInterpolator;
import android.view.animation.OvershootInterpolator;
import android.view.animation.RotateAnimation;
import android.view.animation.ScaleAnimation;
import android.view.animation.TranslateAnimation;

public class AnimController {
	public final int relaSelf = Animation.RELATIVE_TO_SELF;
	public final int relaPar = Animation.RELATIVE_TO_PARENT;
	
	public final int defaultDurationMillis = 350;
	public final int defaultDelayMillis = 0;
	
	public final int Linear = 0;
	public final int Accelerate = 1;
	public final int Decelerate = 2;
	public final int AccelerateDecelerate = 3;
	public final int Bounce = 4;
	public final int Overshoot = 5;
	public final int Anticipate = 6;
	public final int AnticipateOvershoot = 7;
	
	public int defaultInterp = Decelerate; 
	 
	public static AnimController animController;
	
	public static AnimController getInstance(){
		if(animController == null){
			animController = new AnimController();
		}
		return animController;
	}
	
	public interface AnimCallback{
		public void onAnimationStart();
		public void onAnimationEnd();
	}
	

	class MyAnimationListener implements AnimationListener {
		private View view;
		private int visibility;
		private AnimCallback callback;

		/**
		 * 
		 * @param view
		 * @param handle 
		 *  View.GONE  or View.VISIBLE
		 */
		public MyAnimationListener(View view, int visibility) {
			super();
			this.view = view;
			this.visibility = visibility;
		}
		
		public MyAnimationListener(View view, int visibility,AnimCallback callback) {
			super();
			this.view = view;
			this.visibility = visibility;
			this.callback = callback;
		}

		@Override
		public void onAnimationStart(Animation animation) {
//			 view.setVisibility(View.VISIBLE);
			if(callback != null){
				callback.onAnimationStart();
			}
		}

		@Override
		public void onAnimationEnd(Animation animation) {
			view.setVisibility(visibility);
			if(callback != null){
				callback.onAnimationEnd();
			}
		}

		@Override
		public void onAnimationRepeat(Animation animation) {
		}

	}

	/**
	 * 设置动画显示类型、持续时间和执行延迟时间
	 * @param animation
	 * @param interpolatorType
	 * @param durationMillis
	 * @param delayMillis
	 */
	private void setEffect(Animation animation, int interpolatorType,long durationMillis, long delayMillis) {
		switch (interpolatorType) {
		case 0:
			animation.setInterpolator(new LinearInterpolator());
			break;
		case 1:
			animation.setInterpolator(new AccelerateInterpolator());
			break;
		case 2:
			animation.setInterpolator(new DecelerateInterpolator());
			break;
		case 3:
			animation.setInterpolator(new AccelerateDecelerateInterpolator());
			break;
		case 4:
			animation.setInterpolator(new BounceInterpolator());
			break;
		case 5:
			animation.setInterpolator(new OvershootInterpolator());
			break;
		case 6:
			animation.setInterpolator(new AnticipateInterpolator());
			break;
		case 7:
			animation.setInterpolator(new AnticipateOvershootInterpolator());
			break;
		default:
			break;
		}
		animation.setDuration(durationMillis);
		animation.setStartOffset(delayMillis);
	}

	private void baseIn(View view, Animation animation, long durationMillis,long delayMillis) {
		if(view == null/* || view.isShown()*/){
			return;
		}
		setEffect(animation, defaultInterp, durationMillis, delayMillis);
		animation.setAnimationListener(new MyAnimationListener(view,View.VISIBLE));
		view.startAnimation(animation);
	}

	private void baseOut(View view, Animation animation, long durationMillis,long delayMillis) {
		if(view == null || !view.isShown()){
			return;
		}
		setEffect(animation, defaultInterp, durationMillis, delayMillis);
		animation.setAnimationListener(new MyAnimationListener(view,View.GONE));
		view.startAnimation(animation);
	}
	
	/**
	 * 淡入，默认持续350毫秒，0秒延迟
	 * @param view
	 */
	public void fadeIn(View view) {
		fadeIn(view, defaultDurationMillis, defaultDurationMillis);
	}

	/**
	 * 淡入
	 * @param view
	 * @param durationMillis 
	 * @param delayMillis
	 */
	public void fadeIn(View view, long durationMillis, long delayMillis) {
		AlphaAnimation animation = new AlphaAnimation(0f, 1f);
		baseIn(view, animation, durationMillis, delayMillis);
	}
	
	/**
	 * 淡出 默认持续350毫秒，0秒延迟
	 * @param view
	 */
	public void fadeOut(View view) {
		fadeOut(view, defaultDurationMillis, defaultDurationMillis);
	}

	/**
	 * 淡出
	 * @param view
	 * @param durationMillis
	 * @param delayMillis
	 */
	public void fadeOut(View view, long durationMillis, long delayMillis) {
		AlphaAnimation animation = new AlphaAnimation(1f, 0f);
		baseOut(view, animation, durationMillis, delayMillis);
	}

	/**
	 * 从左侧进入  默认持续350毫秒，0秒延迟
	 * @param view
	 */
	public void slideLeftIn(View view) {
		slideLeftIn(view, defaultDurationMillis, defaultDelayMillis);
	}
	
	/**
	 * 从左侧进入
	 * @param view
	 * @param durationMillis
	 * @param delayMillis
	 */
	public void slideLeftIn(View view, long durationMillis, long delayMillis) {
		TranslateAnimation animation = new TranslateAnimation(relaSelf, -1f,relaSelf, 0f, relaSelf, 0f, relaSelf, 0f);
		baseIn(view, animation, durationMillis, delayMillis);
	}
	
	public void slideLeftIn(View view, long durationMillis, long delayMillis,AnimCallback callback) {
		TranslateAnimation animation = new TranslateAnimation(relaSelf, -1f,relaSelf, 0f, relaSelf, 0f, relaSelf, 0f);
		if(view == null){
			return;
		}
		setEffect(animation, defaultInterp, durationMillis, delayMillis);
		animation.setAnimationListener(new MyAnimationListener(view,View.VISIBLE,callback));
		view.startAnimation(animation);
	}
	
	
	/**
	 * 从右侧进入  默认持续350毫秒，0秒延迟
	 * @param view
	 */
	public void slideRightIn(View view) {
		slideRightIn(view, defaultDurationMillis, defaultDelayMillis);
	}

	/**
	 * 从右侧进入
	 * @param view
	 * @param durationMillis
	 * @param delayMillis
	 */
	public void slideRightIn(View view, long durationMillis, long delayMillis) {
		TranslateAnimation animation = new TranslateAnimation(relaSelf, 1f,relaSelf, 0f, relaSelf, 0f, relaSelf, 0f);
		baseIn(view, animation, durationMillis, delayMillis);
	}
	
	/**
	 * 从右侧进入
	 * @param view
	 * @param durationMillis
	 * @param delayMillis
	 */
	public void slideRightIn(View view, long durationMillis, long delayMillis,AnimCallback callback) {
		TranslateAnimation animation = new TranslateAnimation(relaSelf, 1f,relaSelf, 0f, relaSelf, 0f, relaSelf, 0f);
		if(view == null){
			return;
		}
		setEffect(animation, defaultInterp, durationMillis, delayMillis);
		animation.setAnimationListener(new MyAnimationListener(view,View.VISIBLE,callback));
		view.startAnimation(animation);
	}

	/**
	 * 从上面进入
	 * @param view
	 * @param durationMillis
	 * @param delayMillis
	 */
	public void slideUpIn(View view, long durationMillis, long delayMillis) {
		TranslateAnimation animation = new TranslateAnimation(relaPar, 0f,relaPar, 0f, relaPar, -1f, relaPar, 0f);
		baseIn(view, animation, durationMillis, delayMillis);
	}
	
	/**
	 * 从左侧移出
	 * @param view
	 * @param durationMillis
	 * @param delayMillis
	 */
	public void slideLeftOut(View view, long durationMillis, long delayMillis) {
		TranslateAnimation animation = new TranslateAnimation(relaPar, 0f,relaPar, -1f, relaPar, 0f, relaPar, 0f);
		baseOut(view, animation, durationMillis, delayMillis);
	}
	
	
	/**
	 * 从左侧移出
	 * @param view
	 * @param durationMillis
	 * @param delayMillis
	 * @param callback
	 */
	public void slideLeftOut(View view, long durationMillis, long delayMillis,AnimCallback callback) {
		TranslateAnimation animation = new TranslateAnimation(relaPar, 0f,relaPar, -1f, relaPar, 0f, relaPar, 0f);
		if(view == null){
			return;
		}
		setEffect(animation, Accelerate, durationMillis, delayMillis);
		animation.setAnimationListener(new MyAnimationListener(view,View.GONE,callback));
		view.startAnimation(animation);
	}
	

	/**
	 * 从上面移出
	 * @param view
	 * @param durationMillis
	 * @param delayMillis
	 */
	public void slideUpOut(View view, long durationMillis, long delayMillis) {
		TranslateAnimation animation = new TranslateAnimation(relaPar, 0f,relaPar, 0f, relaPar, 0f, relaPar, -1);
		baseOut(view, animation, durationMillis, delayMillis);
	}

	/**
	 * 从右侧移出
	 * @param view
	 * @param durationMillis
	 * @param delayMillis
	 */
	public void slideRightOut(View view, long durationMillis, long delayMillis) {
		TranslateAnimation animation = new TranslateAnimation(relaSelf, 0f,relaSelf, 1f, relaSelf, 0f, relaSelf, 0f);
		baseOut(view, animation, durationMillis, delayMillis);
	}
	
	public void slideRightOut(View view, long durationMillis, long delayMillis,AnimCallback callback) {
		TranslateAnimation animation = new TranslateAnimation(relaSelf, 0f,relaSelf, 1f, relaSelf, 0f, relaSelf, 0f);
		if(view == null){
			return;
		}
		setEffect(animation, Accelerate, durationMillis, delayMillis);
		animation.setAnimationListener(new MyAnimationListener(view,View.GONE,callback));
		view.startAnimation(animation);
	}
	
	/**
	 * 从底侧移出
	 * @param view
	 * @param durationMillis
	 * @param delayMillis
	 */
	public void slideBottomOut(View view, long durationMillis, long delayMillis) {
		TranslateAnimation animation = new TranslateAnimation(relaPar, 0f,relaPar, 0f, relaPar, 0f, relaPar, 1f);
		baseOut(view, animation, durationMillis, delayMillis);
	}
	
	/**
	 * 从底侧移入
	 * @param view
	 * @param durationMillis
	 * @param delayMillis
	 */
	public void slideBottomIn(View view, long durationMillis, long delayMillis) {
		TranslateAnimation animation = new TranslateAnimation(relaPar, 0f,relaPar, 0f, relaPar, 1f, relaPar, 0f);
		baseIn(view, animation, durationMillis, delayMillis);
	}

	/**
	 * 从底部正中间放大
	 * @param view
	 * @param durationMillis
	 * @param delayMillis
	 */
	public void scaleIn(View view, long durationMillis, long delayMillis) {
		ScaleAnimation animation = new ScaleAnimation(0f, 1f, 0f, 1f, relaSelf,0.5f, relaSelf, 1f);
		baseIn(view, animation, durationMillis, delayMillis);
	}

	/**
	 * 从底部正中间缩小
	 * @param view
	 * @param durationMillis
	 * @param delayMillis
	 */
	public void scaleOut(View view, long durationMillis, long delayMillis) {
		ScaleAnimation animation = new ScaleAnimation(1f, 0f, 1f, 0f, relaSelf,0.5f, relaSelf, 1f);
		baseOut(view, animation, durationMillis, delayMillis);
	}

	/**
	 * 绕左侧底部逆时针旋转180度 进入
	 * @param view
	 * @param durationMillis
	 * @param delayMillis
	 */
	public void rotateIn(View view, long durationMillis, long delayMillis) {
		RotateAnimation animation = new RotateAnimation(180f, 0f, relaSelf, 0f,relaSelf, 1f);
		baseIn(view, animation, durationMillis, delayMillis);
	}

	/**
	 * 绕左侧底部顺时针旋转180度 移出
	 * @param view
	 * @param durationMillis
	 * @param delayMillis
	 */
	public void rotateOut(View view, long durationMillis, long delayMillis) {
		RotateAnimation animation = new RotateAnimation(0f, 180f, relaSelf, 0f,relaSelf, 1f);
		baseOut(view, animation, durationMillis, delayMillis);
	}

	/**
	 * 正中间旋转放大显示
	 * @param view
	 * @param durationMillis
	 * @param delayMillis
	 */
	public void scaleRotateIn(View view, long durationMillis, long delayMillis) {
		ScaleAnimation animation1 = new ScaleAnimation(0f, 1f, 0f, 1f, relaSelf,0.5f, relaSelf, 0.5f);
		RotateAnimation animation2 = new RotateAnimation(0f, 360f, relaSelf,0.5f, relaSelf, 0.5f);
		AnimationSet animation = new AnimationSet(false);
		animation.addAnimation(animation1);
		animation.addAnimation(animation2);
		baseIn(view, animation, durationMillis, delayMillis);
	}
	/**
	 * 正中间旋转缩小消失
	 * @param view
	 * @param durationMillis
	 * @param delayMillis
	 */
	public void scaleRotateOut(View view, long durationMillis, long delayMillis) {
		ScaleAnimation animation1 = new ScaleAnimation(1f, 0f, 1f, 0f, relaSelf,0.5f, relaSelf, 0.5f);
		RotateAnimation animation2 = new RotateAnimation(0f, 360f, relaSelf,0.5f, relaSelf, 0.5f);
		AnimationSet animation = new AnimationSet(false);
		animation.addAnimation(animation1);
		animation.addAnimation(animation2);
		baseOut(view, animation, durationMillis, delayMillis);
	}

	/**
	 * 从右侧淡入
	 * @param view
	 * @param durationMillis
	 * @param delayMillis
	 */
	public void slideFadeIn(View view, long durationMillis, long delayMillis) {
		TranslateAnimation animation1 = new TranslateAnimation(relaPar, 1f,relaPar, 0f, relaPar, 0f, relaPar, 0f);
		AlphaAnimation animation2 = new AlphaAnimation(0f, 1f);
		AnimationSet animation = new AnimationSet(false);
		animation.addAnimation(animation1);
		animation.addAnimation(animation2);
		baseIn(view, animation, durationMillis, delayMillis);
	}

	/**
	 * 从左侧淡出
	 * @param view
	 * @param durationMillis
	 * @param delayMillis
	 */
	public void slideFadeOut(View view, long durationMillis, long delayMillis) {
		TranslateAnimation animation1 = new TranslateAnimation(relaPar, 0f,relaPar, -1f, relaPar, 0f, relaPar, 0f);
		AlphaAnimation animation2 = new AlphaAnimation(1f, 0f);
		AnimationSet animation = new AnimationSet(false);
		animation.addAnimation(animation1);
		animation.addAnimation(animation2);
		baseOut(view, animation, durationMillis, delayMillis);
	}
}
